#include "IPC_Client_System.h"
#include "gkt_config.h"

#if defined(GKT_CONFIG_FPS_ENABLE) && GKT_CONFIG_FPS_ENABLE

extern G_Message_TypeDef t_message;
extern G_IpcInitTypeDef  IpcParaInit;

G_IpcStatusTypeDef G_Client_System_Cmd_Sync_Send(void)
{
	t_message.pData[t_message.DataLen ++] = 'O';
	t_message.pData[t_message.DataLen ++] = 'K';
    while(!G_IPC_RV_Send_SyncMsg(M02RV,&t_message,NULL,0));
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Cmd_Async_Send(uint8_t type,uint8_t opcode, uint8_t *idata, uint16_t ilen)
{
    G_Message_TypeDef tMsg;

    tMsg.type   = type;
    tMsg.opcode = opcode;
    tMsg.DataLen= ilen;
    tMsg.pData = idata;

    if(TRUE != G_IPC_RV_Send_Msg(M02RV,&tMsg,0))
    {
        return IPC_ERROR_SEND;
    }
    return  IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Cmd_Check_Recv_Data(G_Message_TypeDef *tMsg,G_Message_TypeDef *rMsg)
{
    if(tMsg->type != rMsg->type)
    {
        return IPC_ERROR_SEND;
    }
    
    if(tMsg->opcode != rMsg->opcode)
    {
        return IPC_ERROR_SEND;
    }
    
    if(rMsg->pData[rMsg->DataLen - 2] != 'O' || rMsg->pData[rMsg->DataLen - 1] != 'K')
    {
        return IPC_ERROR_SEND;
    }
    
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Cmd_Sync_Send(uint8_t type,uint8_t opcode, uint8_t *idata, uint16_t ilen,uint8_t *odata,uint32_t *olen)
{
    uint8_t r_Msg_buf[8] = {0};
    G_Message_TypeDef tMsg;
    G_Message_TypeDef rMsg;
  
    tMsg.type   = type;
    tMsg.opcode = opcode;
    tMsg.DataLen= ilen;
    tMsg.pData = idata;
    
    if(MMCU->RV_CTRL.bit.CLK_EN!=0x0a||MMCU->RV_CTRL.bit.RESET!=0x0a||MMCU->RV_CTRL.bit.SLP_STATUS!=0)
    {
        return IPC_ERROR_SEND;
    }
    
    if(odata == NULL)
    {
        rMsg.pData = r_Msg_buf;
    }
    else
    {
        rMsg.pData = odata;
    }
    uint32_t primask=__get_PRIMASK();
    __disable_irq();
    if(TRUE != G_IPC_RV_Send_SyncMsg(M02RV,&tMsg,&rMsg,IPC_SYSTEM_TIME_OUT))
    {
        if(primask==0)  __enable_irq();
        return IPC_ERROR_SEND;
    }
    if(primask==0)  __enable_irq();
    if(IPC_SUCCESS != G_Cmd_Check_Recv_Data(&tMsg,&rMsg))
    {
        return IPC_ERROR_SEND;
    }
    
    *olen = rMsg.DataLen;
    return  IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Client_SendConfigPara(uint8_t *pdata)
{
    IpcParaInit.Ipc_IflashParaCB.IflashRvStartAddr = *(volatile int*)(0xe01f0);//rv flash start
    uint32_t ConfigParaAddr = (uint32_t)&IpcParaInit;
    uint8_t Idata[4] = 
    {
        ConfigParaAddr & 0xff,
        (ConfigParaAddr >> 8) & 0xff,
        (ConfigParaAddr >> 16) & 0xff,
        (ConfigParaAddr >> 24) & 0xff,
    };
    return G_Cmd_Async_Send(IPC_TYPE_SYSTEM,IPC_SYSTEM_PARA_CMD,Idata,4); 
}

#endif


